package com.wnxy.service.impl;

import com.wnxy.entity.Cart;
import com.wnxy.entity.CartVo;
import com.wnxy.entity.Product;
import com.wnxy.mapper.CartMapper;
import com.wnxy.mapper.ProductMapper;
import com.wnxy.service.CartService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 购物车表 服务实现类
 * </p>
 *
 * @author 林夕
 * @since 2023-03-11 04:45:21
 */
@Service
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements CartService {

    @Autowired
    RedisTemplate<String, Object> stringObjectRedisTemplate;
    @Autowired
    ProductMapper productMapper;
    @Override
    public void addCart(Integer userId, Integer weaponId) {
        //Redis使用Hash数据类型
        HashOperations<String, Object, Object> opsForHash = stringObjectRedisTemplate.opsForHash();
        //拿到要加入购物车的商品信息
        Product product = productMapper.selectById(weaponId);
        //先判断该商品是否在购物车当中
        CartVo cartVo1 = (CartVo) opsForHash.get(userId.toString(), weaponId.toString());
        if (cartVo1 == null){
            //未在购物车中,加购
            CartVo cartVo2 = new CartVo();
            cartVo2.setProductId(product.getId());
            cartVo2.setProductName(product.getProductName());
            cartVo2.setProductImgsrc(product.getProductImgsrc());
            cartVo2.setProductPrice(product.getProductPrice());
            cartVo2.setBuyCount(1);
            cartVo2.setSumPrice(product.getProductPrice());

            opsForHash.put(userId.toString(),weaponId.toString(),cartVo2);

        }else {
            //已在购物车中,改变 buyCount 和 sumPrice
            cartVo1.setBuyCount(cartVo1.getBuyCount() + 1);
            cartVo1.setSumPrice(cartVo1.getSumPrice().add(product.getProductPrice()));

            opsForHash.put(userId.toString(),weaponId.toString(),cartVo1);
        }

    }

    @Override
    public List<CartVo> getCartVo(Integer userId) {
        //Redis使用Hash数据类型
        HashOperations<String, Object, Object> opsForHash = stringObjectRedisTemplate.opsForHash();
        List<Object> objectList = opsForHash.values(userId.toString());
        /*
            将List<Object>强转成List<CartVo>  ??看不懂
            List<CartVo> cartVoList = objectList.stream().map(obj -> (CartVo) obj).collect(Collectors.toList());
        */

        List<CartVo> cartVoList = new ArrayList<>();
        for (Object o : objectList) {
            CartVo cartVo = (CartVo) o;
            cartVoList.add(cartVo);
        }

        return cartVoList;
    }

    @Override
    public CartVo updateBuyCount(Integer userId, Integer productId, Integer count) {
        //从Redis中获取该商品信息
        HashOperations<String, Object, Object> opsForHash = stringObjectRedisTemplate.opsForHash();
        CartVo cartVo = (CartVo) opsForHash.get(userId.toString(), productId.toString());
        //通过判断前端传过来的count的对应按钮将商品的计件数进行加减
        if (count == -1){
            //数量 -1
            cartVo.setBuyCount(cartVo.getBuyCount() - 1);
            //总额 减去单价
            cartVo.setSumPrice(cartVo.getSumPrice().subtract(cartVo.getProductPrice()));
        } else if (count == 1) {
            //数量 +1
            cartVo.setBuyCount(cartVo.getBuyCount() + 1);
            //总额 加上单价
            cartVo.setSumPrice(cartVo.getSumPrice().add(cartVo.getProductPrice()));
        } else {
            //count=0的情况,即为删除按钮,数量和总额清零
            cartVo.setBuyCount(0);
            cartVo.setSumPrice(BigDecimal.ZERO);
        }

        //判断商品件数,以此来处理Redis中的数据
        if (cartVo.getBuyCount() > 0){
            //将最新的购物车数据放入缓存中
            opsForHash.put(userId.toString(),productId.toString(),cartVo);
        } else {
            //看做删除
            opsForHash.delete(userId.toString(),productId.toString());
        }
        return cartVo;
    }

    @Override
    public BigDecimal totalPrice(Integer userId, Integer[] weaponIds) {
        HashOperations<String, Object, Object> opsForHash = stringObjectRedisTemplate.opsForHash();
        //初始总额为0
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (Integer weaponId : weaponIds) {
            CartVo cartVo = (CartVo) opsForHash.get(userId.toString(), weaponId.toString());
            totalPrice =totalPrice.add(cartVo.getSumPrice());
        }
        return totalPrice;
    }

    @Override
    public List<CartVo> getCartVoPreview(Integer userId, Integer[] weaponIds) {
        HashOperations<String, Object, Object> opsForHash = stringObjectRedisTemplate.opsForHash();
        ArrayList<CartVo> cartVoList = new ArrayList<>();
        for (Integer weaponId : weaponIds) {
            CartVo cartVo = (CartVo) opsForHash.get(userId.toString(), weaponId.toString());
            cartVoList.add(cartVo);
        }
        return cartVoList;
    }
}
